package com.societyGames.flashForms
{
	import com.societyGames.system.EventObject;
	
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;

	public class TreeViewContainer extends Sprite implements IChangeSize
	{
		private var _nodes:Vector.<DisplayObject> = new Vector.<DisplayObject>();
		private var _sizeChangedEventObject:EventObject;
		private var _isExpanded:Boolean = true;
		private var _desiredHeight:Number;
		private var _desiredWidth:Number;
		
		public function TreeViewContainer()
		{
			this._sizeChangedEventObject = new EventObject(this, "SIZE_CHANGED");
		}
		
		public override function set width(value:Number):void
		{
			this._desiredWidth = value;
		}
		
		public override function set height(value:Number):void
		{
			this._desiredHeight = value;
		}
		
		public function get sizeChangedEventObject():EventObject
		{
			return this._sizeChangedEventObject;
		}
		
		public function get nodeCount():int
		{
			return this._nodes.length;
		}
		
		public function addNode(displayObject:DisplayObject):void
		{
			this._nodes.push(displayObject);
			var changeSize:IChangeSize = displayObject as IChangeSize;
			if (changeSize != null)
			{
				changeSize.sizeChangedEventObject.addEventListener(nodeSizeChanged);
			}
			if (this._isExpanded)
			{
				if (this._nodes.length > 1)
				{
					var previous:DisplayObject = DisplayObject(this._nodes[this._nodes.length - 2]);	
					displayObject.y = previous.y + previous.height;
				}
				else
				{
					displayObject.y =  0;
				}
				this.addChild(displayObject);
				this._sizeChangedEventObject.dispatchEvent();
			}
		}
		
		public function removeNode(displayObject:DisplayObject):void
		{
			var index:int = this._nodes.indexOf(displayObject);
			if (index != -1)
			{
				this._nodes.splice(index, 1);
				var changeSize:IChangeSize = displayObject as IChangeSize;
				if (changeSize != null)
				{
					changeSize.sizeChangedEventObject.removeEventListener(nodeSizeChanged);
				}
				if (this._isExpanded)
				{
					this.removeChild(displayObject);
					var nextY:Number = displayObject.y;
					for (var i:int = index; i < this._nodes.length; i++)
					{	
						this._nodes[i].y = nextY;
						nextY += this._nodes[i].height;
					}
					this._sizeChangedEventObject.dispatchEvent();
				}
			}
		}
		
		public function clear():void
		{
			for each (var displayObject:DisplayObject in this._nodes)
			{
				var changeSize:IChangeSize = displayObject as IChangeSize;
				if (changeSize != null)
				{
					changeSize.sizeChangedEventObject.removeEventListener(nodeSizeChanged);
				}
				this.removeChild(displayObject);
			}
			this._nodes.length = 0;
			this._sizeChangedEventObject.dispatchEvent();
		}
		
		public function get isExpanded():Boolean
		{
			return this._isExpanded;	
		}
		
		public function set isExpanded(value:Boolean):void
		{
			if (this._isExpanded != value)
			{
				this._isExpanded = value;
				if (this._isExpanded)
				{
					//Add the elements in.
					var nextY:Number = 0;
					for (var addIndex:int = 0; addIndex < this._nodes.length; addIndex++)
					{
						var addDisplayObject:DisplayObject = this._nodes[addIndex];
						addDisplayObject.y = nextY;
						this.addChild(addDisplayObject);
						nextY += addDisplayObject.height;						
					}
				}
				else
				{
					//Clear
					for (var removeIndex:int = 0; removeIndex < this._nodes.length; removeIndex++)
					{
						this.removeChild(this._nodes[removeIndex]);
					}
				}
				this._sizeChangedEventObject.dispatchEvent(); //TODO: this might not need to be raised if there are no nodes.
			}
		}
		
		private function nodeSizeChanged(event:Event):void
		{
			var index:int = this._nodes.indexOf(event.target);
			for (index++; index < this._nodes.length; index++)
			{
				this._nodes[index].y = this._nodes[index - 1].y + this._nodes[index - 1].height;
			}
			this._sizeChangedEventObject.dispatchEvent();
		}
	}
}